<?php
if (! defined ( 'IN_BIC' )) {
    die ( '非法核心访问来源!' );
}
/**
 *系统核心
 *
 * @package Bic
 * @author Bic
 * @version $Id: kernel.php 2010年3月27日
 * @copyright (c) 2009 Bic
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 *
 * Minimum Requirement: PHP 5.2.*
 */
class App extends Bic_Base{
    
    private static $_version = '1.0 Alpha build 12032103';

    /**
     * 调试级别
     * 
     * 设置为false时，为关闭debug
     * 不为false时，有以下几种调试
     *  bic:框架级别调试捕获E_USER_ERROR、E_USER_WARNING、E_USER_NOTICE三类错误。不包括手动throw的错误
     *  bicAll:在bic的基础上，增加包括E_USER_ERROR、E_USER_WARNING、E_USER_NOTICE所有错误。不包括手动throw的错误
     *  sys:系统级别调试。不对错误进行后期捕获。开启系统的error_reporting(E_ALL ^ E_NOTICE);
     *  sysAll:系统级别调试。不对错误进行后期捕获。开启系统的error_reporting(E_ALL);
     * @var bool
     */
    public static $_debugMode = 'bic';

    /**
     * 开启路由功能
     * @var bool
     */
    private static $_router = true;

    /**
     * 是否添加默认路由
     * @var bool
     */
    private static $_addDefaultRoute = true;

    private static $_instance=null;

    private function __construct(){}

    public static function getInstance(){
        if (!self::$_instance instanceof self){
            self::$_instance = new self;
            /**
             * 关闭error_reporting(0)
             */
            self::$_instance->debug(false);
        }
        return self::$_instance;
    }

    /**
     * 文件导入
     * @param string $type
     * @param string $name
     */
    public static function import($type,$name,$option=array('debug'=>false)){
        $type = strtolower($type);
        switch ($type){
            case 'controller':
            case 'model':
            case 'view':
                $file = APP_DIR.$type.DS.$name.'.php';
                break;
            case 'core':
            case 'bic':
                $file = BIC.$name.'.php';
            case 'lib':
                $file = LIB.$name.'.php';
                break;
            default:
                $path = BIC.rtrim(str_replace(array('.'),DS,$type),DS);
                $file = ('' != $name) ? $path.DS.$name.'.php' : $path.'.php';

                break;
        }
        if ($option['debug'] == true){
            debug($file);
        }
        if (!is_file($file)){
            throw new Bic_Exception("文件加载出错:[{$file}]不存在");
        }
        require $file;
        return $file;
    }
    
    /**
     *加载自定义Model
     * @param type $modelName
     * @return \Bic_Model_Abstract 
     */
    public static function loadModel($modelName){
        $className = "Model_".ucfirst($modelName);
        class_exists($className,false) or App::import('model', $modelName);
        return  new $className();
    }

    /**
     * 系统初始化
     */
    public static function init(){
        if (self::$_router){
                $http = Bic_Controller_Request_Http::getInstance();
                $uri = $http->getRequestUri();
                //加载用户配置路由
                if(!defined('APP_DIR')){
                    define('APP_DIR',ROOT.'app'.DS);
                }
                if (is_file(APP_DIR.'config'.DS.'routes.php')){
                    require_once APP_DIR.'config'.DS.'routes.php';
                }else{
                    throw new Bic_Exception("用户自定义路由配置加载失败:".APP_DIR.'config'.DS.'routes.php');
                }

                //添加默认路由
                if (self::$_addDefaultRoute){
                    Bic_Router::addDefaultRoutes();
                }
                Bic_Router::getCurrentRoute($uri);
                App::dispatch();
        }
    }

    /**
     * 分配器
     * @return bool
     */
    private static function dispatch(){
        $view = Bic_View::getInstance();
        /**
         * 加载Controller
         * @var unknown_type
         */
        $current_controller = 'Controller_'.Bic_Router::getCurrentController();
        $current_controller_file = strtolower(Bic_Router::getCurrentController());
        $current_Action = Bic_Router::getCurrentAction();

        /**
         * 初始化Controller
         */
        self::import('controller',$current_controller_file);
        //self::import(APP.'controller'.DS.$current_controller_file);
        if (!class_exists($current_controller)){
            throw new Bic_Exception("系统尚未定义控制器[{$current_controller}]");
        }
        $controller = new $current_controller();

        /**
         * 注册路由(url)变量
         * 	注册为$_GET变量
         * 	注册为模板变量
         */
        foreach(Bic_Router::getParams() as $router_key=>$router_val){
            $_GET[$router_key] = $router_val;
            $view->setVar($router_key,$router_val);
        }

        //$controller -> assign(Bic_Router::getParams());

        /**
         * 初始化Action
         */
        if (!method_exists($current_controller, $current_Action)){
            throw new Bic_Exception("系统尚未定义行为[\${$current_controller}->{$current_Action}()]");
        }

        $controller -> $current_Action();

        return true;
    }
    
    public static function info(){
        echo 'BicPHP current version: '.self::version();
    }
    
    public static function version(){
        return self::$_version;
    }

    /**
     * 移除默认路由
     */
    public static function removeDefaultRoute(){
        self::$_addDefaultRoute = false;
    }

    /**
     *设置调试级别
     * @param type $type 
     */
    public static function setDebug($type=0){
        switch($type){
            /**
             * 框架级别调试 
             */
            case 'bic':
            case 'bicAll':
                ini_set('display_errors', 1);
                //这里不能关闭，
                //关闭了就不能显示语法级别错误
                error_reporting(E_ALL);
                /**
                 * 设置自定义错误
                 * 在这里捕获除了语法错误之外的错误
                 */
                set_error_handler(array('Bic_Exception', 'errorHandle'));
                /**
                 * 设置顶级异常
                 */
                set_exception_handler(array('Bic_Exception','exceptionHandle'));
                break;
            case 'system':
            case 'sys':
                ini_set('display_errors',1);
                error_reporting(E_ALL ^ E_NOTICE);
            case 'systemAll':
            case 'sysAll':
                ini_set('display_errors',1);
                error_reporting(E_ALL);
                break;
            case 'close':
            default:
                error_reporting(0);
                break;
        }
        self::$_debugMode = $type;
    }
    public static function getDebugMode(){
        return self::$_debugMode;
    }
}
